epci_fonds_fm <- st_read("C:/Users/Rania El Fahli/Documents/Fonds de carte IGN 2023/EPCI.shp")
## Reading layer `EPCI' from data source
## `C:\Users\Rania El Fahli\Documents\Fonds de carte IGN 2023\EPCI.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 1243 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 107388.8 ymin: 6046546 xmax: 1242443 ymax: 7110479
## Projected CRS: RGF93 Lambert 93
dep_fm <- st_read("C:/Users/Rania El Fahli/Documents/Fonds de carte IGN 2023/DEPARTEMENT.shp")
## Reading layer `DEPARTEMENT' from data source
## `C:\Users\Rania El Fahli\Documents\Fonds de carte IGN 2023\DEPARTEMENT.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 96 features and 5 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 99040 ymin: 6046546 xmax: 1242443 ymax: 7110479
## Projected CRS: RGF93 Lambert 93
epci_fonds_fm <- epci_fonds_fm |>
dplyr::filter(NATURE != "Etablissement public territorial")
# check projection
# st_crs(epci_fonds_fm)
# st_crs(dep_fm)
donnes_stat_locales <- list.files("C:/Users/Rania El Fahli/Documents/tuto_carto/tuto_carto", pattern = "*.xlsx",
full.names = TRUE)
donnes_stat_locales_f <- lapply(donnes_stat_locales, function(x) read_excel(x, skip = 3))
source("C:/Users/Rania El Fahli/Documents/Atlas/Cartes/Scripts/codes_epci_dom.R") # vecteur contenant les codes des EPCI d'Outre-Mer pour filtrer + facilement.
rename_colonne <- function(x) {
names(x) <- str_replace(names(x), "Part des familles monoparentales ", "part_fam_mono_")
return(x)
}
donnes_stat_locales_f <- donnes_stat_locales_f |>
lapply(rename_colonne)
donnes_stat_locales_f <- lapply(donnes_stat_locales_f, function(x) filter(x, !Code %in% epci_dom))
donnes_stat_locales_f <- lapply(donnes_stat_locales_f, function(x)select(x, -c(Libellé)))
donnes_serie_epci_fm <- plyr::join_all(donnes_stat_locales_f, by = "Code", type = "left")
donnes_serie_epci_fm <- donnes_serie_epci_fm |>
mutate_at(vars(starts_with("part_fam_mono")), as.numeric)
donnes_long <- donnes_serie_epci_fm |>
pivot_longer(!c(Code),
names_to = "annee",
values_to = "part_fam_mono")
discret_jenks <- classInt::classIntervals(donnes_long$part_fam_mono, style = "jenks", n = 4)
discret_jenks_v <- c(4.4, 10.0, 12.7, 15.7, 22.5)
palette <- rcartocolor::carto_pal(n = 4, name = "PinkYl")
donnes_carto <- epci_fonds_fm |>
left_join(donnes_serie_epci_fm, by = c("CODE_SIREN" = "Code"))
Le “faceting” permet de générer un graphique/carte pour chaque groupe de la variable utilisée. Cela reviendrait à subset la table principale par groupe et réaliser la même carte à partir de chacune de ces sous-tables. Avec {ggplot2}, on utilise la fonction facet_wrap().
En amont, on transforme la table au format long pour créer une variable année qui contient trois groupes correspondant aux 3 années de la table principale : 2009, 2014 et 2020.
# on transforme la table au format long pour avoir une variable "année" qu'on utilise
# ensuite pour le faceting
donnes_carto_l <- donnes_carto |>
select(c(CODE_SIREN, geometry, starts_with("part_fam_mono"))) |>
pivot_longer(!c(CODE_SIREN, geometry),
names_to = "annee",
values_to = "part_fam_mono")
donnes_carto_l$annee <- as.factor(donnes_carto_l$annee)
donnes_carto_l$annee <- donnes_carto_l$annee |>
forcats::fct_recode(
"2009" = "part_fam_mono_2009",
"2014" = "part_fam_mono_2014",
"2020" = "part_fam_mono_2020"
) # on modifie les données pour l'affichage des labels ensuite
theme_carte_rania <- theme(
panel.background = element_blank(),
panel.grid = element_blank(),
axis.line = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks.x = element_blank(),
axis.ticks.y = element_blank(),
legend.box = "vertical",
legend.key.width = unit(0.4, "cm"),
legend.key.height = unit(1, "cm"),
legend.key = element_rect(colour = "transparent",),
legend.background = element_rect(fill='transparent', colour = "grey35", size = 0.8),
legend.title = element_text(size = 18),
legend.text = element_text(size = 16),
legend.key.size = unit(1.7,'cm'),
legend.spacing.y = unit(1.3, 'cm'),
legend.title.align = 0,
plot.title = element_text(size = 22, face = "bold"),
plot.subtitle = element_text(size = 20, face = "bold"),
plot.caption = element_text(size = 12, hjust = 0, face = "italic"),
# élements relatifs aux labels du facet_wrap
strip.background = element_rect(
color="grey35", fill="transparent", size=0.8, linetype="solid"),
strip.text = element_text(size = 18, face = "bold.italic")
)
donnes_carto_l$discret <- cut(donnes_carto_l$part_fam_mono, c(discret_jenks_v))
mes_labels <- function(breaks) {
do.call(\(...) sprintf('De %s à %s', ...),
cbind.data.frame(breaks[-length(breaks)] , breaks[-1]))
}
labels_fam_mono <- mes_labels(discret_jenks[["brks"]])
p <- donnes_carto_l |>
ggplot() +
geom_sf(aes(fill = discret),color = "grey55", lwd = 0.2 ) +
scale_fill_manual(values = palette, labels = labels_fam_mono)+
geom_sf(data= dep_fm, fill = "transparent", color = "grey35", lwd = 0.5) +
labs(fill = "Part des familles monoparentales (%)",
title = "Evolution de la part des familles monoparentales entre 2009 et 2020",
subtitle = "A l'échelle des EPCI",
caption = paste0("Source : Recensement de la population, exploitation complémentaire, Insee.",
sep = "\n", "IGN 2023.")) +
theme_carte_rania +
facet_wrap(~annee, nrow = 2, ncol = 2) + # modifier les arguments nrow et ncol pour changer la disposition des cartes
guides(fill = guide_legend(title.position="top", title.hjust = 0))
# lemon::reposition_legend() pour changer la disposition de la légende (utiliser les espaces vides)
lemon::reposition_legend(p, "center", panel = "panel-2-2")
Si les cartes sont réalisées avec le package {tmap}, l’équivalent est tm_facets()
donnes_carto_l |>
tm_shape() +
tm_polygons("part_fam_mono", style = "jenks", n = 4, palette = palette,
border.col = "grey55", lwd = 0.2,
labels = c("4,5 à 10", "10 à 12,7", "12,7 à 15,7", "15,7 à 22,5"),
title = "Part des familles monoparentales (%)")+
tm_facets("annee") +
tm_layout(
main.title = paste0("Evolution de la part des familles monoparentales entre 2009 et 2020",
sep = "\n","A l'échelle des EPCI" ),
main.title.size = 2,
main.title.fontface = "bold",
main.title.position = c("left", "top"),
panel.label.fontface = "bold",
panel.label.bg.color = "white",
panel.label.color = "grey35",
panel.label.size = 3,
legend.title.size = 10,
legend.text.size = 2,
legend.frame = F
) # changer au choix l'afficage du panel avec les arguments de tm_layout()
Générer plusieurs cartes avec tm_facets
On utilise les fonctions de base R, mfrow() et par().
Voir les exemples de la vignette du package : Faceting with Mapsf Package : https://riatelab.github.io/mapsf/articles/web_only/how_to_create_faceted_maps.html
Dans le cas où les cartes sont réalisées individuellement (elles ne dépendent pas d’une même table), différents packages permettent de les arranger sur une même image :
# je génère deux cartes individuelles pour l'exemple
# je retire le titre & la caption que je rajouterai sur l'image finale
carte_2009 <- donnes_carto_l |>
dplyr::filter(annee == "2009") |>
ggplot() +
geom_sf(aes(fill = discret),color = "grey55", lwd = 0.2 ) +
scale_fill_manual(values = palette, labels = labels_fam_mono)+
geom_sf(data= dep_fm, fill = "transparent", color = "grey35", lwd = 0.5) +
labs(fill = "Part des familles monoparentales (%)") +
theme_carte_rania +
guides(fill = guide_legend(title.position="top", title.hjust = 0))
carte_2020 <- donnes_carto_l |>
dplyr::filter(annee == "2020") |>
ggplot() +
geom_sf(aes(fill = discret),color = "grey55", lwd = 0.2 ) +
scale_fill_manual(values = palette, labels = labels_fam_mono)+
geom_sf(data= dep_fm, fill = "transparent", color = "grey35", lwd = 0.5) +
labs(fill = "Part des familles monoparentales (%)") +
theme_carte_rania +
guides(fill = guide_legend(title.position="top", title.hjust = 0))
# guide_area() permet de créer un espace vide pour y placer la légende, sinon elle est placée par défaut comme ici.
# (carte_2009 + carte_2020) / guide_area() = les deux cartes côte à côte sur une première ligne,
(carte_2009 + carte_2020) +
plot_layout(guides = "collect") +
plot_annotation(
title = "Evolution de la part des familles monoparentales entre 2009 et 2020",
subtitle = "A l'échelle des EPCI",
caption = paste0("Source : Recensement de la population, exploitation complémentaire, Insee.",
sep = "\n", "IGN 2023."),
tag_levels = list(c("2009", "2020")),
theme = theme(
plot.caption = element_text(size = 22, face = "italic" ),
plot.title = element_text(size = 30),
plot.subtitle = element_text(size = 30), # on peut utiliser directement la fonction theme() de ggplot2 pour personnaliser la mise en forme des différents éléments.
)) & theme(plot.tag = element_text(size = 30))
Assembler les cartes avec Patchwork
Ici il vaut mieux extraire la légende en amont et enregistrer à nouveaux les cartes sans légende.
legende <- ggpubr::get_legend(carte_2009)
carte_2009 <- carte_2009 +
theme(legend.position = "none")
carte_2020 <- carte_2020 +
theme(legend.position = "none")
deux_cartes <- plot_grid(carte_2009 , carte_2020 ) # on met les cartes côte à côte
# on assemble les éléments
deux_cartes_legende <- ggdraw() +
draw_plot(deux_cartes) +
draw_plot(legende, scale = 2,
x = -0.02,
y = 0.05)
# ggdraw() permet d'assembler différents types d'objets (labels, ggplots, tables gt, images)
# Pour les différents éléments on peut utiliser ggdraw et draw_labels, ou bien enregistrer les cartes assemblées puis utiliser annotate()
deux_cartes_legende +
annotate(geom = "text",
label = paste0("Source : Recensement de la population, exploitation complémentaire, Insee.",
sep = "\n", "IGN 2023."),
fontface = 'italic',
x = 0.85, y = 0.02, size = 5 ) +
annotate(geom = "text",
label = paste0("Evolution de la part des familles monoparentales entre 2009 et 2020", sep = "\n",
"A l'échelle des EPCI"),
y = 0.95, x = 0.47, size = 8 ,
fontface = "bold") +
annotate(geom = "text",
label = "2009",
x = 0.118, y = 0.85,
fontface = "italic",
size = 10
) +
annotate(geom = "text",
label = "2020",
fontface = "italic",
size = 10,
y = 0.85, x = 0.62)
Assembler les cartes avec Cowplot - méthode 1
ggdraw() permet de choisir plus précisement ici la taille et le ratio des éléments. On aurait pu sinon réaliser la carte ainsi, toujours avec Cowplot :
deux_cartes_legende <- plot_grid(carte_2009, legende, carte_2020,
align = "vh",
nrow = 1,
rel_widths = c(3, 0.85, 3)) # le ratio de chaque élément
deux_cartes_legende + annotate(geom = "text",
label = paste0("Source : Recensement de la population, exploitation complémentaire, Insee.",
sep = "\n", "IGN 2023."),
fontface = 'italic',
x = 0.85, y = 0.02, size = 5 ) +
annotate(geom = "text",
label = paste0("Evolution de la part des familles monoparentales entre 2009 et 2020", sep = "\n",
"A l'échelle des EPCI"),
y = 0.95, x = 0.47, size = 8 ,
fontface = "bold") +
annotate(geom = "text",
label = "2009",
x = 0.118, y = 0.85,
fontface = "italic",
size = 10
) +
annotate(geom = "text",
label = "2020",
fontface = "italic",
size = 10,
y = 0.85, x = 0.62)
Assembler les cartes avec Cowplot - méthode 2
Références : Ggplot2: Elegant Graphics for Data Analysis, 9 Arranging plots (https://ggplot2-book.org/arranging-plots), 16 Faceting (https://ggplot2-book.org/facet) Geocomputation with R : https://r.geocompx.org/